/*
Copyright (C) 2010  Christoph Schnack, Berlin (Germany)

This file is part of Tribuit.

    Tribuit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Tribuit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Tribuit.  If not, see <http://www.gnu.org/licenses/>.
*/
package PictureMappingInterrogation;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.Timer;

import GuiTools.*;
import Mainframe.Mainframe;
import PDPictureEditor.*;
import PictureDescription.*;
import PictureMappingInterrogation.PictureMappingInterrogationSettings.Options;
import Settings.*;

/**
 * @author Christoph Schnack
 *
 */
public class PictureMappingInterrogation implements PicturePanelParent {
	PictureStorage PICSTO;
	Settings SET;
	Language LANG;
	HashMap<String,Vector<String>> DATA;
	Options OPTIONS;
	MDTribuitFrame pvFrame;
	JComboBox zoomCB;
	Mainframe MAINFRAME;
	PicturePanel picturePanel;
	Vector<PNUComponent> pnups = new Vector<PNUComponent>();
	String colName;
	boolean highlighting=false,highlightSwitch=false;
	int hlIndex;
	Timer flashTimer;
	MDManager PIDM;
	JPanel pnuPanel;
	
	//interrogation
	TribuitTextField titleTF;
	JLabel sectionL,nameL,collectionL;
	JButton stopFlashBtn,hideAllTagsBtn,showAllTagsBtn;
	int collectionIndex,puSize,puIndex;
	String[] dataKeySet;
	Vector<String> currentPus;
	PictureCollection currentCollection;
	PictureUnit currentPU;
	
	public PictureMappingInterrogation(Settings set,PictureStorage picsto,MDManager pidm,HashMap<String,Vector<String>> data, Options opts){
		SET = set;
		LANG = set.getLanguage();
		PICSTO = picsto;
		DATA = data;
		OPTIONS = opts;
		PIDM = pidm;
		buildGui();
	}
	
		
	public void buildGui(){
		flashTimer = new Timer(600,new FlashTimerListener());
		pvFrame = new MDTribuitFrame(LANG.getPictureMapInterrogation(),PIDM);
		picturePanel = new PicturePanel(SET,pvFrame,this);
		
		JLabel nameLabel = new JLabel(LANG.getName()+":");
		nameLabel.setFont(new Font(Font.SANS_SERIF,Font.BOLD,14));
		nameL = new JLabel("---");
		nameL.setToolTipText("---");
		nameL.setOpaque(false);
		nameLabel.setOpaque(false);
		JLabel collectionLabel = new JLabel(LANG.getCollection()+":");
		collectionLabel.setFont(new Font(Font.SANS_SERIF,Font.BOLD,14));
		collectionL = new JLabel(colName);
		collectionL.setToolTipText(colName);
		collectionL.setOpaque(false);
		collectionLabel.setOpaque(false);
		JLabel sectionLabel = new JLabel(LANG.getSection()+":");
		sectionLabel.setFont(new Font(Font.SANS_SERIF,Font.BOLD,14));
		sectionL = new JLabel("---");
		sectionL.setToolTipText("---");
		sectionL.setOpaque(false);
		sectionLabel.setOpaque(false);
		nameLabel.setMinimumSize(nameLabel.getPreferredSize());
		collectionLabel.setMinimumSize(collectionLabel.getPreferredSize());
		sectionLabel.setMinimumSize(sectionLabel.getPreferredSize());
		
		JPanel infoPanel = new JPanel(new GridBagLayout());
		infoPanel.setBorder(BorderFactory.createTitledBorder(LANG.getMetainformation()));
		//JButton tInfoBtn = new JButton(new ImageIcon(GuiTools.TRIBUITHOME+File.separator+"graphics"+File.separator+"infoIcon.png"));
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.fill = GridBagConstraints.NONE;
		gbc.weightx = 0;
		gbc.gridy=1;
		gbc.gridx=1;
		infoPanel.add(nameLabel,gbc);
		++gbc.gridy;
		infoPanel.add(collectionLabel,gbc);
		++gbc.gridy;
		infoPanel.add(sectionLabel,gbc);
		gbc.gridy=1;
		gbc.gridx=2;
		gbc.weightx=3;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.insets = new Insets(0,5,0,0);
		gbc.anchor = GridBagConstraints.WEST;
		infoPanel.add(nameL,gbc);
		++gbc.gridy;
		infoPanel.add(collectionL,gbc);
		++gbc.gridy;
		infoPanel.add(sectionL,gbc);
		infoPanel.setPreferredSize(new Dimension(200,infoPanel.getPreferredSize().height));
		
		titleTF = new TribuitTextField(SET,10);
		titleTF.addActionListener(new EnterListener());
		JPanel titlePanel = new JPanel();
		titlePanel.add(titleTF);
		titlePanel.setBorder(BorderFactory.createTitledBorder(LANG.getTitle()));
		
		
		stopFlashBtn = new JButton(LANG.getStopFlash());
		stopFlashBtn.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				stopHighlightTags();
			}
		});
		hideAllTagsBtn = new JButton(LANG.getHideAll());
		hideAllTagsBtn.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				for(int i=0;i<pnups.size();i++){
					pnups.elementAt(i).setHideTags(true);
				}
				picturePanel.repaintImagePanel();
			}
		});
		
		showAllTagsBtn = new JButton(LANG.getDisplayAll());
		showAllTagsBtn.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				for(int i=0;i<pnups.size();i++){
					pnups.elementAt(i).setHideTags(false);
				}
				picturePanel.repaintImagePanel();
			}
		});
		JPanel tagButtonsPanel = new JPanel();
		tagButtonsPanel.setOpaque(false);
		tagButtonsPanel.add(hideAllTagsBtn);
		tagButtonsPanel.add(showAllTagsBtn);
		tagButtonsPanel.add(stopFlashBtn);
		pnuPanel = new JPanel();
		pnuPanel.setBackground(Color.white);
		pnuPanel.setLayout(new GridBagLayout());
		JScrollPane jsp = new JScrollPane(pnuPanel);
		jsp.getVerticalScrollBar().setUnitIncrement(50);
		jsp.setPreferredSize(new Dimension(250,300));
		JPanel tagPanel = new JPanel(new GridBagLayout());
		GridBagConstraints gb = new GridBagConstraints();
		gb.fill =GridBagConstraints.BOTH;
		gb.anchor =GridBagConstraints.NORTHWEST;
		gb.weighty = 1;
		tagPanel.add(jsp,gb);
		gb.weighty = 0;
		gb.gridy = 1;
		tagPanel.add(tagButtonsPanel,gb);
		tagPanel.setBorder(BorderFactory.createTitledBorder(LANG.getTags()+":"));
		
		final JComboBox zoomCB = new JComboBox(GuiTools.getZOOMSTEPS());
		zoomCB.setSelectedItem("1.00");
		zoomCB.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				picturePanel.setZoom(Double.parseDouble((String)zoomCB.getSelectedItem()));
			}
		});
		LabelPanel zoomLP = new LabelPanel("zoom",zoomCB);
		zoomLP.setOpaque(false);
		
		JPanel tagButtonsPanelBottom = new JPanel(new FlowLayout(FlowLayout.LEFT));
		tagButtonsPanelBottom.setOpaque(false);
		tagButtonsPanelBottom.add(zoomLP);
		
		JPanel westPanel = new JPanel();
		westPanel.setBackground(Color.gray);
		westPanel.setLayout(new GridBagLayout());
		gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.insets = new Insets(10,10,0,10);
		gbc.gridy = 1;
		gbc.weighty = 0;
		gbc.weightx=1;
		westPanel.add(infoPanel,gbc);
		++gbc.gridy;
		westPanel.add(titlePanel,gbc);
		++gbc.gridy;
		gbc.weighty = 2;
		westPanel.add(tagPanel,gbc);
		++gbc.gridy;
		gbc.weighty = 0;
		gbc.insets = new Insets(10,10,10,10);
		westPanel.add(tagButtonsPanelBottom,gbc);
		
		TScrollPane westTSP =  new TScrollPane(westPanel);
		westTSP.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		JButton closeBTN = new JButton(LANG.getClose());
		closeBTN.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				pvFrame.dispose();
			}
		});
		JButton solveBTN = new JButton(LANG.getSolve());
		solveBTN.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				solve();
			}
		});
		JButton enterBTN = new JButton("enter");
		enterBTN.addActionListener(new EnterListener());
		JPanel buttonPanel = new JPanel();
		buttonPanel.setBackground(GuiTools.BGCOLOR);
		buttonPanel.add(enterBTN);
		buttonPanel.add(solveBTN);
		buttonPanel.add(closeBTN);
		pvFrame.getContentPane().add(BorderLayout.NORTH,new Header(LANG.getPictureMapInterrogation()));
		pvFrame.getContentPane().add(BorderLayout.CENTER, picturePanel);
		pvFrame.getContentPane().add(BorderLayout.WEST, westTSP);
		pvFrame.getContentPane().add(BorderLayout.SOUTH, buttonPanel);
		pvFrame.setResizable(true);
		pvFrame.showUp(50,50);
		startInterrogation();
	}
	
	public void startInterrogation(){
		dataKeySet = DATA.keySet().toArray(new String[]{});
		collectionIndex = 0;
		puIndex = -1;
		currentCollection = PICSTO.getCollection(dataKeySet[collectionIndex]);
		currentPus = DATA.get(dataKeySet[collectionIndex]);
		testNextPU();
	}
	
	public void checkAnswers(){
		PNUPanel p;
		if(currentPU.hasTitle()){
			String input = titleTF.getText();
			if(input!=null && input.equals("")){
				GuiTools.showEmptyOrInvalidInputWarning(LANG, pvFrame, LANG.getTitle());
				titleTF.requestFocus();
				return;
			}
			if(!input.equals(currentPU.getTitle())){
				JOptionPane.showMessageDialog(pvFrame, LANG.getWrongAnswerAtTitle(), LANG.getAttention(), JOptionPane.WARNING_MESSAGE,new ImageIcon(GuiTools.loadImageFromGraphics("sadSmiley.png")));
				titleTF.selectAll();
				titleTF.requestFocus();
				return;
			}
		}
		if(currentPU.hasPictureNameUnits()){
			String input,name;
			for(PNUComponent pnup : pnups){
				p = (PNUPanel) pnup;
				input = p.getText();
				name = p.getTagName();
				if(input!=null && !input.equals("")){
					if(!OPTIONS.getRegardCase()){
						input = input.toLowerCase();
						name = name.toLowerCase();
						
					}
					if(!input.equals(name)){
						JOptionPane.showMessageDialog(pvFrame, LANG.getWrongAnswerAtTag()+" "+(p.getIndex()+1), LANG.getAttention(), JOptionPane.WARNING_MESSAGE,new ImageIcon(GuiTools.loadImageFromGraphics("sadSmiley.png")));
						p.markTextField();
						return;
					}
				}
				else{
					GuiTools.showEmptyOrInvalidInputWarning(LANG, pvFrame, LANG.getTagName()+" "+(p.getIndex()+1));
					p.markTextField();
					return;
				}
			}
		}
		JOptionPane.showOptionDialog(pvFrame,LANG.getAllAnswersCorrect(), LANG.getMessage(), JOptionPane.WARNING_MESSAGE, JOptionPane.OK_OPTION, new ImageIcon(GuiTools.loadImageFromGraphics("correctIcon.png")), new String[]{LANG.getContinue()}, LANG.getContinue());
		testNextPU();
	}
	
	public void solve(){
		if(currentPU.hasTitle()){
			titleTF.setText(currentPU.getTitle());
		}
		PNUPanel p;
		if(currentPU.hasPictureNameUnits()){
			for(PNUComponent pnup : pnups){
				p = (PNUPanel) pnup;
				p.solve();
			}
		}
	}
	
	public void testNextPU(){
		if(puIndex<currentPus.size()-1){
			currentPU = currentCollection.getPictureUnit(currentPus.elementAt(++puIndex));
			picturePanel.setImage(GuiTools.loadImage(GuiTools.PATHTOPICTUREMAPS+File.separator+currentCollection.getName()+File.separator+currentPU.getName()+File.separator+"image"));
			setAnswerPanels();
		}
		else{
			if(collectionIndex<dataKeySet.length-1){
				currentCollection = PICSTO.getCollection(dataKeySet[++collectionIndex]);
				currentPus = DATA.get(currentCollection.getName());
				puIndex = -1;
				testNextPU();
			}
			else{
				finishTest();
			}
		}
	}
	
	public void finishTest(){
		int ans = JOptionPane.showOptionDialog(pvFrame,LANG.getInterrogationFinished(), LANG.getMessage(), JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE,null, new String[]{LANG.getRestart(),LANG.getQuit()}, LANG.getQuit());
		if(ans == JOptionPane.OK_OPTION){
			startInterrogation();
		}
		else pvFrame.dispose();
	}
	
	public void setAnswerPanels(){
		pnups = new Vector<PNUComponent>();
		pnuPanel.removeAll();
		boolean hasTags = currentPU.hasPictureNameUnits(); 
		nameL.setText(currentPU.getName());
		sectionL.setText(currentPU.getSection());
		collectionL.setText(currentCollection.getName());
		titleTF.setText("");
		titleTF.setEnabled(currentPU.hasTitle());
		if(hasTags){
			Vector<PictureNameUnit> pnus = currentPU.getTags();
			int index=0;
			GridBagConstraints pnuGbc = new GridBagConstraints();
			pnuGbc.fill = GridBagConstraints.BOTH;
			pnuGbc.anchor = GridBagConstraints.NORTHWEST;
			pnuGbc.weighty=0;
			pnuGbc.weightx=2;
			pnuGbc.insets = new Insets(5,0,0,0);
			PNUPanel p;
			for(PictureNameUnit pnu : pnus){
				p = new PNUPanel(pnu,index++);
				pnups.add(p);
				pnuGbc.gridy++;
				pnuPanel.add(p,pnuGbc);
			}
		}
		stopFlashBtn.setEnabled(hasTags);
		hideAllTagsBtn.setEnabled(hasTags);
		showAllTagsBtn.setEnabled(hasTags);
		pvFrame.pack();
	}
	
	class EnterListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			checkAnswers();
		}
	}
	
	class PNUPanel extends JPanel implements PNUComponent{
		Vector<PictureTagUnit> positions;
		String name;
		int index;
		PictureNameUnit pnu;
		boolean hideTags = false,infoPanelIsShown = false;
		JPanel panel,infoPanel;
		JCheckBox hideTagsCB;
		JScrollPane infoPane;
		TribuitTextField nameTF;
		
		public PNUPanel(PictureNameUnit p,int ind){
			super();
			panel = this;
			pnu = p;
			positions = pnu.getTags();
			name = pnu.getName();
			index = ind;
			buildGUI();
		}
		
		private void buildGUI(){
			nameTF = new TribuitTextField(SET,10);
			nameTF.addActionListener(new EnterListener());
			JLabel indexLabel = new JLabel(""+(index+1));
			JPanel namePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
			namePanel.add(indexLabel);
			namePanel.add(nameTF);
			indexLabel.setFont(new Font(Font.SANS_SERIF,Font.BOLD,16));
			hideTagsCB = new JCheckBox(LANG.getHideTags());
			hideTagsCB.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					hideTags = hideTagsCB.isSelected();
					picturePanel.repaintImagePanel();
				}
			});
			JButton flashButton = new JButton(LANG.getFlash());
			flashButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					highlightTags(index);
				}
			});
			infoPanel = new JPanel();
			CustomTextArea infoCTA = new CustomTextArea(pnu.getInfoText());
			infoPane = new JScrollPane(infoCTA);
			infoPane.setPreferredSize(new Dimension(200,100));
			JButton infoButton = new JButton();
			try{
				infoButton.setIcon(new ImageIcon(ImageIO.read(new File("graphics"+File.separator+"infoIcon.png"))));
			}
			catch(IOException e){
				e.printStackTrace();
			}
			infoButton.addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e){
					infoPanel.removeAll();
					if(!infoPanelIsShown){
						infoPanel.add(infoPane);
						infoPanelIsShown = true;
					}
					else infoPanelIsShown = false;
					pvFrame.setPreferredSize(pvFrame.getSize());
					pvFrame.pack();
				}
			});
			infoButton.setEnabled(pnu.hasInfoText());
			JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
			buttonsPanel.add(flashButton);
			buttonsPanel.add(infoButton);
			buttonsPanel.add(hideTagsCB);
			panel.setLayout(new GridBagLayout());
			GridBagConstraints gbc = new GridBagConstraints();
			gbc.anchor = GridBagConstraints.NORTHWEST;
			gbc.fill = GridBagConstraints.BOTH;
			gbc.weightx = 1;
			panel.add(namePanel,gbc);
			gbc.gridy = 1;
			panel.add(infoPanel,gbc);
			gbc.gridy = 2;
			panel.add(buttonsPanel,gbc);
			
		}
		public boolean getHideTags() {
			return hideTags;
		}
		
		public void setHideTagsCBEnabled(boolean arg){
			hideTagsCB.setEnabled(arg);
		}
		
		public void setHideTags(boolean arg) {
			hideTags = arg;
			hideTagsCB.setSelected(arg);
		}
		
		public boolean getShouldHideTags() {
			return false;
		}
		
		public boolean hasTags() {
			pnu.hasTags();
			return false;
		}
		
		public int getIndex() {
			return index;
		}
		
		public void setIndex(int i) {
			index = i;
		}
		
		public String getTagName(){
			return name;
		}
		
		public String getText(){
			return nameTF.getText();
		}
		
		
		public Vector<PictureTagUnit> getPictureTags() {return positions;}
		public void addPictureTagUnit(PictureTagUnit ptu) {}
		public void disableDeleteTagButton() {}
		public void selectNothing() {}
		public void setAddTagButtonActive(boolean arg) {}
		public void setPictureTagUnit(int index, PictureTagUnit ptu) {}
		public void updateTagArmPanel() {}
		
		public void markTextField(){
			nameTF.selectAll();
			nameTF.requestFocus();
		}
		
		public void solve(){
			nameTF.setText(name);
		}
	}

	

	public Vector<PNUComponent> getPictureNameUnits() {
		return pnups;
	}

	public boolean getShowAllTags() {
		return false;
	}
	
	public void highlightTags(int index){
		hlIndex=index;
		highlighting=true;
		picturePanel.setHighlighting(true);
		picturePanel.setHlIndex(hlIndex);
		picturePanel.setHighlightVector(true);
		flashTimer.start();
	}
	class FlashTimerListener implements ActionListener{
		public void actionPerformed(ActionEvent e){
			highlightSwitch=highlightSwitch?false:true;
			picturePanel.setHighlightSwitch(highlightSwitch?false:true);
			picturePanel.repaintImagePanel();
		}
	}
	
	public void stopHighlightTags(){
		flashTimer.stop();
		picturePanel.setHighlighting(false);
		SwingUtilities.invokeLater(new Runnable(){
			public void run(){
				picturePanel.repaintImagePanel();
			}
		});
	}
	
	public void addPictureTagUnitTo(PictureTagUnit ptu, int setTagIndex) {}
	public void setPictureTagUnit(int index, int ptuIndex, PictureTagUnit pu) {}
	public void setTagArm(int ind, int tagInd, int armInd, TADE tade) {}
}

